package me.ydq.core;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.Accessors;
import me.ydq.convert.ColumnConvert;
import me.ydq.core.sql.Sql;
import me.ydq.dialect.Dialect;
import me.ydq.misc.Fn;

import java.util.List;

@Getter
@Accessors(fluent = true)
@AllArgsConstructor(staticName = "of")
public class SqlCriteria<T> {
    Class<T>     cls;
    Sql          sql;
    Fn<T, ?>     column;//自动根据 Entity::getField 获取列名
    String       rawSqlColumn;//方便一些需要手写列名，如日期函数转化一下当前列 等场景
    List<Object> params;

    public Object param() {
        //noinspection SequencedCollectionMethodCanBeUsed
        return params.get(0);
    }

    public Object param(int index) {
        return params.get(index);
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, List<Object> params) {
        return of(cls, builder, null, null, params);
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, Fn<T, ?> column) {
        return of(cls, builder, column, null, List.of());
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, String rawSqlColumn) {
        return of(cls, builder, null, rawSqlColumn, List.of());
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, Fn<T, ?> column, List<Object> params) {
        return of(cls, builder, column, null, params);
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, String rawSqlColumn, List<Object> params) {
        return of(cls, builder, null, rawSqlColumn, params);
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, Fn<T, ?> column, String param) {
        return of(cls, builder, column, null, List.of(param));
    }

    public static <T> SqlCriteria<T> of(Class<T> cls, Sql builder, String rawSqlColumn, String param) {
        return of(cls, builder, null, rawSqlColumn, List.of(param));
    }

    public String toSql(Dialect dialect, ColumnConvert columnConvert) {
        return sql.build(dialect, columnConvert, this);
    }
}
